<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  
  <title>Android-IPC通讯Binder和Service的关系 | 清风向阳</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  
    <meta name="keywords" content="Joker,Joker's Blog" />
  
  <meta name="description" content="任何系统都有自己的跨进程通讯，Android是基于Linux，所以都会兼容Linux的通讯机制，包括有管道，信号，socket等等。基于Android自身的特点，有提出了自己的通讯方式Binder机制。接下来就来具体的介绍。">
<meta name="keywords" content="Binder,Android-IPC">
<meta property="og:type" content="article">
<meta property="og:title" content="Android-IPC通讯Binder和Service的关系">
<meta property="og:url" content="http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/index.html">
<meta property="og:site_name" content="清风向阳">
<meta property="og:description" content="任何系统都有自己的跨进程通讯，Android是基于Linux，所以都会兼容Linux的通讯机制，包括有管道，信号，socket等等。基于Android自身的特点，有提出了自己的通讯方式Binder机制。接下来就来具体的介绍。">
<meta property="og:updated_time" content="2017-09-15T07:00:19.000Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Android-IPC通讯Binder和Service的关系">
<meta name="twitter:description" content="任何系统都有自己的跨进程通讯，Android是基于Linux，所以都会兼容Linux的通讯机制，包括有管道，信号，socket等等。基于Android自身的特点，有提出了自己的通讯方式Binder机制。接下来就来具体的介绍。">
  
  
    <link rel="icon" href="/favicon_pic.ico">
  
  <link href="//cdn.bootcss.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" type="text/css">
  <link rel="stylesheet" href="/css/style.css">
  <script src="/js/pace.min.js"></script>
  

  
  

</head>

<body>
  <div id="container">
      <header id="header">
    <div id="banner"></div>
    <div id="header-outer">
        <div id="header-menu" class="header-menu-pos animated">
            <div class="header-menu-container">
                <a href="/" class="left">
                    <span class="site-title">Joker&#39;s Blog</span>
                </a>
                <nav id="header-menu-nav" class="right">
                    
                    <a  href="/">
                        <i class="fa fa-home"></i>
                        <span>Home</span>
                    </a>
                    
                    <a  href="/archives">
                        <i class="fa fa-archive"></i>
                        <span>Archives</span>
                    </a>
                    
                    <a  href="/about">
                        <i class="fa fa-user"></i>
                        <span>About</span>
                    </a>
                    
                </nav>
                <a class="mobile-header-menu-button">
                    <i class="fa fa-bars"></i>
                </a>
            </div>
        </div>
        <div id="header-row">
            <div id="logo">
                <a href="/">
                    <img src="/images/avatar.jpg" alt="logo">
                </a>
            </div>
            <div class="header-info">
                <div id="header-title">
                    
                    <h2>
                        Joker&#39;s Blog
                    </h2>
                    
                </div>
                <div id="header-description">
                    
                    <h3>
                        一个认真的技术博客
                    </h3>
                    
                </div>
            </div>
            <nav class="header-nav">
                <div class="social">
                    
                        <a title="Joker"  href="//joker-studio.pub">
                            <i class="fa fa-home fa-2x"></i></a>
                    
                        <a title="Github" target="_blank" href="//github.com/mjjde">
                            <i class="fa fa-github fa-2x"></i></a>
                    
                </div>
            </nav>
        </div>
    </div>
</header>
      <div class="outer">
        <section id="main" class="body-wrap"><article id="post-Android-IPC通讯Binder和Service的关系" class="article article-type-post" itemscope itemprop="blogPost">
  <div class="article-inner">
    
      <header class="article-header">
        
  
    <h1 class="post-title" itemprop="name">
      Android-IPC通讯Binder和Service的关系
    </h1>
    <div class="post-title-bar">
      <ul>
          
              <li>
                  <i class="fa fa-book"></i>
                  
                      <a href="/categories/Android技术/">Android技术</a>
                  
              </li>
          
        <li>
          <i class="fa fa-calendar"></i>  2016-01-05
        </li>
        <li>
          <i class="fa fa-eye"></i>
          <span id="busuanzi_value_page_pv"></span>
        </li>
      </ul>
    </div>
  

          
      </header>
    
    <div class="article-entry post-content" itemprop="articleBody">
      
            
            <blockquote>
<p>任何系统都有自己的跨进程通讯，Android是基于Linux，所以都会兼容Linux的通讯机制，包括有管道，信号，socket等等。基于Android自身的特点，有提出了自己的通讯方式Binder机制。接下来就来具体的介绍。<br><a id="more"></a></p>
<h4 id="Binder机制"><a href="#Binder机制" class="headerlink" title="Binder机制"></a><a href="#Binder_u673A_u5236" title="Binder机制"></a>Binder机制</h4></blockquote>
<p>Android中系统的服务基本都是基于Binder，我们在应用层使用的getService()方法调用系统服务。那么这一切是如何进行的呢。</p>
<p>Binder是一种架构，涉及到客户端，服务端，Binder驱动。系统有一个Binder类它将这三个模块连接在一起。Android系统已经帮我们实现了Binder驱动，ServiceManager和系统相关的Service。对于我们开发者来说，我们需要自己去实现需要的Service和Client就可以进行IPC通讯了。</p>
<p>一个Binder服务端就相当于一个Binder对象，一旦被创建，就会在开启一个隐藏线程用来接受client的请求，接受到消息之后就会回调onTransact方法。onTransact方法会根据条件实现不同的服务，那么要使用一个Binder服务就必须要重写onTransact方法。</p>
<p>既然服务端已经具备了接受消息的能力，那么服务端就可以调用transact方法发送消息给服务端，这两个方法是相对应的，我们看下这两个方法的API.</p>
<figure class="highlight aspectj"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">protected</span> <span class="keyword">boolean</span> onTransact(<span class="keyword">int</span> code, Parcel data, Parcel reply,</div><div class="line">    <span class="keyword">int</span> flags) <span class="keyword">throws</span> RemoteException</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">boolean</span> transact(<span class="keyword">int</span> code, Parcel data, Parcel reply,</div><div class="line">    <span class="keyword">int</span> flags)<span class="keyword">throws</span> RemoteException</div></pre></td></tr></table></figure>
<p>从方法参数中我们就可以知道对应关系。code表示要调用的方法的id,data是调用方法的参数，reply是方法的返回。flags为标记，一般为0.</p>
<p>在Binder驱动中，任意一个服务端Binder被创建后，都在会在驱动中也会创建一个mRemote对象，该对象也是类型也是Binder类。要使用服务端的服务都是通过mRemote来完成的。</p>
<p>在客户端中要使用服务端服务，我们就要获取mRemote的引用，调用transact来发送给服务端消息，服务端接受到我们需要它完成的任务就会运作起来。</p>
<p>在这样的架构里，我们产生了2个Binder对象，一个在服务端，一个在Binder驱动中。对于远程调用来说，我们都是直接调用的是Binder驱动中的mRemote对象。该对象在去调用服务端的Binder对象。</p>
<h4 id="基于Binder架构的代码设计"><a href="#基于Binder架构的代码设计" class="headerlink" title="基于Binder架构的代码设计"></a><a href="#u57FA_u4E8EBinder_u67B6_u6784_u7684_u4EE3_u7801_u8BBE_u8BA1" title="基于Binder架构的代码设计"></a>基于Binder架构的代码设计</h4><p>上面说过了，系统已经为我们完成了很多任务了，我们开发者只需要进行两个端的设计就可以实现Binder通信了。</p>
<h5 id="Service端设计"><a href="#Service端设计" class="headerlink" title="Service端设计"></a><a href="#Service_u7AEF_u8BBE_u8BA1" title="Service端设计"></a>Service端设计</h5><p>在服务端的设计有2点，第一点是服务端需要提高的服务，这个要根据不同业务有开发者设计。第二点是我们上面说过的必须实现onTransact方法。</p>
<figure class="highlight aspectj"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BookSerivce</span> <span class="keyword">extends</span> <span class="title">Binder</span> </span>&#123;</div><div class="line"></div><div class="line">List&lt;String&gt; books ;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="title">BookSerivce</span><span class="params">()</span></span>&#123;</div><div class="line">    books = <span class="keyword">new</span> ArrayList&lt;String&gt;();</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="meta">@Override</span></div><div class="line"><span class="keyword">protected</span> <span class="function"><span class="keyword">boolean</span> <span class="title">onTransact</span><span class="params">(<span class="keyword">int</span> code, Parcel data, Parcel reply, <span class="keyword">int</span> flags)</span> <span class="keyword">throws</span> RemoteException </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">return</span> <span class="keyword">super</span>.<span class="title">onTransact</span><span class="params">(code, data, reply, flags)</span></span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">int</span> <span class="title">getBookSize</span><span class="params">()</span></span>&#123;</div><div class="line">    <span class="function"><span class="keyword">return</span> books.<span class="title">size</span><span class="params">()</span></span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="function"><span class="keyword">void</span> <span class="title">addBook</span><span class="params">(String book)</span></span>&#123;</div><div class="line">        books.add(book);</div><div class="line">&#125;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>在OnTransact方法里我们需要根据code的不同去调用不同的方法，这个是需要服务端和客户端约定好的。比如我们这里这样的约定</p>
<figure class="highlight arduino"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">   data.enforceInterface(<span class="string">"BookSerivce"</span>);</div><div class="line"><span class="built_in">switch</span> (code)&#123;</div><div class="line">    <span class="built_in">case</span> <span class="number">1000</span>:</div><div class="line">        <span class="keyword">int</span> <span class="built_in">size</span> = getBookSize();</div><div class="line">        reply.writeInt(<span class="built_in">size</span>);</div><div class="line">        <span class="built_in">break</span>;</div><div class="line">    <span class="built_in">case</span> <span class="number">2000</span>:</div><div class="line">        <span class="keyword">String</span> name = data.<span class="built_in">readString</span>();</div><div class="line">        addBook(name);</div><div class="line">        <span class="built_in">break</span>;</div><div class="line"></div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>发送消息code为1000我们就调用getBookSize(),code为2000，我们调用addBook(String name)方法。</p>
<h5 id="Client端设计"><a href="#Client端设计" class="headerlink" title="Client端设计"></a><a href="#Client_u7AEF_u8BBE_u8BA1" title="Client端设计"></a>Client端设计</h5><p>客户端我们要做两件事，第一是要获取到Binder驱动里的mRemote。第二是要调用mRemote方法transact通知到服务端。</p>
<figure class="highlight mipsasm"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">IBinder mRemote = null<span class="comment">;</span></div><div class="line">int code = <span class="number">2000</span><span class="comment">;</span></div><div class="line"><span class="keyword">android.os.Parcel </span>_data = <span class="keyword">android.os.Parcel.obtain();</span></div><div class="line"><span class="keyword">android.os.Parcel </span>_reply = <span class="keyword">android.os.Parcel.obtain();</span></div><div class="line">_data.writeInterfaceToken(DESCRIPTOR)<span class="comment">;</span></div><div class="line">_data.writeString(<span class="string">"aa"</span>)<span class="comment">;</span></div><div class="line">mRemote.transact(code, _data, _reply, <span class="number">0</span>)<span class="comment">;</span></div><div class="line">_data.recycle()<span class="comment">;</span></div><div class="line">_reply.recycle()<span class="comment">;</span></div></pre></td></tr></table></figure>
<p>client端将data 和 reply打包发送给Binder驱动，Binder驱动将会挂起当前线程，并将请求交给服务端onTransact方法，服务端处理完后通知Binder驱动取消挂起，client端就可以得要数据了。这里服务端和Binder驱动是共享内存的，不然系统会将数据内存拷贝在Binder驱动层一次，服务端处理的时候又会将数据内存拷贝到服务端，这样会copy两次，是不适合的。</p>
<p>接下来我们看如何获取Binder驱动中的mRemote，系统为我们提供的方法是Service。</p>
<h5 id="Service"><a href="#Service" class="headerlink" title="Service"></a><a href="#Service" title="Service"></a>Service</h5><p>我们可以利用Android给我们提供的Service来获取到Binder驱动的mRemote。系统给我们提供了两个方法来起开服务。</p>
<figure class="highlight fortran"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> ComponentName startService(<span class="keyword">Intent</span> service)</div></pre></td></tr></table></figure>
<p>该方法开启服务端后，客户端没有立马获得服务端的Binder</p>
<figure class="highlight arduino"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">public</span> <span class="keyword">boolean</span> bindService(Intent service, ServiceConnection conn,</div><div class="line">   <span class="keyword">int</span> flags)</div></pre></td></tr></table></figure>
<p>这个方法在启动服务端后，在启动成功后会回调参数中的ServiceConnection conn。</p>
<figure class="highlight routeros"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">public<span class="built_in"> interface </span>ServiceConnection &#123;    </div><div class="line">     public void onServiceConnected(ComponentName name, IBinder service);</div><div class="line">      public void onServiceDisconnected(ComponentName name);</div><div class="line">      &#125;</div></pre></td></tr></table></figure>
<p>其中onServiceConnected方法的参数Service就是我们所需要的Binder驱动中得mRemote.</p>
<p>我们在编写Service是需要重写onBind(Intent intent) 方法要求放回一个Binder类型的对象。这里也就是服务端的Binder。</p>
<h4 id="AIDL编写IPC通信"><a href="#AIDL编写IPC通信" class="headerlink" title="AIDL编写IPC通信"></a><a href="#AIDL_u7F16_u5199IPC_u901A_u4FE1" title="AIDL编写IPC通信"></a>AIDL编写IPC通信</h4><p>以上我们已经零碎的了解了如何完成Binder通信了。接下来我们就是呀AIDL来实现一个完整的程序。</p>
<p>AIDL是Android接口定义语言。可以帮我们创建一个完整的客户端Binder.下面我们在AndroidStudio上完成AIDL开发</p>
<ol>
<li>新建项目test,new 一个AIDL文件，其命名都是以I开头的，这不是必须得，但是都遵循这样的规范。</li>
<li><p>我们发现在AS自动给我们创建了一个aidl目录，里面是一项目包名为名建立的文件目录，该目录下面就是我们刚刚建立的aidl文件。</p>
<figure class="highlight sql"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">// IBookAidlInterface.aidl</div><div class="line">package com.location.joker.deft.aidl;</div><div class="line">// <span class="keyword">Declare</span> <span class="keyword">any</span> non-<span class="keyword">default</span> types here <span class="keyword">with</span> <span class="keyword">import</span> statements</div><div class="line"></div><div class="line"><span class="keyword">interface</span> IBookAidlInterface &#123;</div><div class="line"></div><div class="line">            &#125;</div></pre></td></tr></table></figure>
</li>
</ol>
<p>3.对于基本类型Andorid是可以知道传输的，而其他的对象需要实现Parcelable接口。<br>public class Book implements Parcelable {<br>public int bookId;<br>public String bookName;</p>
<figure class="highlight cs"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div></pre></td><td class="code"><pre><div class="line">@<span class="function">Override</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">describeContents</span>(<span class="params"></span>) &#123;</div><div class="line">    <span class="keyword">return</span> <span class="number">0</span>;</div><div class="line">&#125;</div><div class="line"></div><div class="line">@<span class="function">Override</span></div><div class="line"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">writeToParcel</span>(<span class="params">Parcel dest, <span class="keyword">int</span> flags</span>) &#123;</div><div class="line">    dest.writeInt(<span class="keyword">this</span>.bookId);</div><div class="line">    dest.writeString(<span class="keyword">this</span>.bookName);</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="title">Book</span>(<span class="params"><span class="keyword">int</span> bookId ,String bookName</span>) </span>&#123;</div><div class="line">    <span class="keyword">this</span>.bookId = bookId;</div><div class="line">    <span class="keyword">this</span>.bookName= bookName;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">protected</span> <span class="title">Book</span>(<span class="params">Parcel <span class="keyword">in</span></span>) </span>&#123;</div><div class="line">    <span class="keyword">this</span>.bookId = <span class="keyword">in</span>.readInt();</div><div class="line">    <span class="keyword">this</span>.bookName = <span class="keyword">in</span>.readString();</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="keyword">public</span> <span class="keyword">static</span> final Parcelable.Creator&lt;Book&gt; CREATOR = <span class="keyword">new</span> Parcelable.Creator&lt;Book&gt;() &#123;</div><div class="line">    <span class="function"><span class="keyword">public</span> Book <span class="title">createFromParcel</span>(<span class="params">Parcel source</span>) </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Book(source);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="function"><span class="keyword">public</span> Book[] <span class="title">newArray</span>(<span class="params"><span class="keyword">int</span> size</span>) </span>&#123;</div><div class="line">        <span class="keyword">return</span> <span class="keyword">new</span> Book[size];</div><div class="line">    &#125;</div><div class="line">&#125;;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>在AS中我们可以自动生成上面代码。</p>
<ol>
<li>建立好实体类后我们需要在aidl中声明：新建aidl文件命名Book.aidl</li>
</ol>
<figure class="highlight abnf"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">// Book.aidl</div><div class="line">package com.location.joker.deft.aidl<span class="comment">;</span></div><div class="line">parcelable  Book<span class="comment">;</span></div></pre></td></tr></table></figure>
<ol>
<li>我们在第二步中编写服务端需要提供的服务函数。</li>
</ol>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// IBookAidlInterface.aidl</span></div><div class="line"><span class="keyword">package</span> com.location.joker.deft.aidl;</div><div class="line"><span class="keyword">import</span> com.location.joker.deft.aidl.Book;</div><div class="line"><span class="comment">// Declare any non-default types here with import statements</span></div><div class="line"></div><div class="line"><span class="class"><span class="keyword">interface</span> <span class="title">IBookAidlInterface</span> </span>&#123;</div><div class="line">    <span class="function"><span class="keyword">void</span> <span class="title">addBook</span><span class="params">(in Book book)</span></span>;</div><div class="line">    <span class="function">List&lt;Book&gt; <span class="title">getBooks</span><span class="params">()</span></span>;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>注意：</p>
<p>1.我们需要导入包，即使Book和我们是同一个文件下面，依然要导入包。</p>
<p>2.我们在build.gradle中是否有以下配置：</p>
<figure class="highlight stylus"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">     sourceSets &#123;</div><div class="line">main &#123;</div><div class="line">    java<span class="selector-class">.srcDirs</span> = [<span class="string">'src/main/java'</span>, <span class="string">'src/main/aidl'</span>]</div><div class="line">    resources<span class="selector-class">.srcDirs</span> = [<span class="string">'src/main/java'</span>, <span class="string">'src/main/aidl'</span>]</div><div class="line">    aidl<span class="selector-class">.srcDirs</span> = [<span class="string">'src/main/aidl'</span>]</div><div class="line">    res<span class="selector-class">.srcDirs</span> = [<span class="string">'src/main/res'</span>]</div><div class="line">    assets<span class="selector-class">.srcDirs</span> = [<span class="string">'src/main/assets'</span>]</div><div class="line">&#125;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>以上都确认好了我们rebuild下项目，就会在build/generated/source/aidl下面生成文件IBookAidlInterface.java<br>这个类是一个接口，包括了抽象Stub类和Proxy代理类，Stub继承了Binder，继承了IBookAidlInterface接口，但是并没有去实现我们的服务方法，这是要留给去创建服务Binder再实现的。Stub中有一个方法asInterface,这个方法是用来分辨远程调用还是本地调用的，如果是本地调用就知道调用服务端的服务方法就可以，如果是远程调用的，就要使用proxy代理类了。</p>
<p>我们可以看到在proxy类里面实现了接口的两个方法，这两个方法的实现相当于client要调用mRemote的过程，打包相关数据调用transact方法发给服务端。</p>
<p>IBookAidlInterface定义好了我们就要使用Service了。</p>
<figure class="highlight java"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div></pre></td><td class="code"><pre><div class="line"> <span class="keyword">public</span> <span class="class"><span class="keyword">class</span> <span class="title">BookService</span> <span class="keyword">extends</span> <span class="title">Service</span> </span>&#123;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> List&lt;Book&gt; bookList = <span class="keyword">new</span> ArrayList&lt;&gt;();</div><div class="line"></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCreate</span><span class="params">()</span> </span>&#123;</div><div class="line">        <span class="keyword">super</span>.onCreate();</div><div class="line">        Log.d(<span class="string">"aidl"</span>, <span class="string">"BookService--------------onCreate"</span>);</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="meta">@Nullable</span></div><div class="line">    <span class="meta">@Override</span></div><div class="line">    <span class="function"><span class="keyword">public</span> IBinder <span class="title">onBind</span><span class="params">(Intent intent)</span> </span>&#123;</div><div class="line">        <span class="keyword">return</span> mBinder;</div><div class="line">    &#125;</div><div class="line"></div><div class="line">    <span class="keyword">private</span> <span class="keyword">final</span> IBookAidlInterface.Stub mBinder = <span class="keyword">new</span> IBookAidlInterface.Stub()&#123;</div><div class="line"></div><div class="line"><span class="meta">@Override</span></div><div class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">addBook</span><span class="params">(Book book)</span> <span class="keyword">throws</span> RemoteException </span>&#123;</div><div class="line">    <span class="keyword">synchronized</span> (bookList) &#123;</div><div class="line">        bookList.add(book);</div><div class="line">    &#125;</div><div class="line">&#125;</div><div class="line"></div><div class="line"><span class="meta">@Override</span></div><div class="line"><span class="function"><span class="keyword">public</span> List&lt;Book&gt; <span class="title">getBooks</span><span class="params">()</span> <span class="keyword">throws</span> RemoteException </span>&#123;</div><div class="line">    <span class="keyword">synchronized</span> (bookList) &#123;</div><div class="line">        <span class="keyword">return</span> bookList;</div><div class="line">    &#125;</div><div class="line">    &#125;</div><div class="line">    &#125;;</div><div class="line">&#125;</div></pre></td></tr></table></figure>
<p>这个Service实现了接口里的Stub类，并且将该对象通过方法onBind返回。这样Service一旦启动成功，就会返回一个Binder驱动层的mRemote来提供给客户端使用。就可以完成基于Binder的IPC通讯了。</p>

            <div class="post-copyright">
    <div class="content">
        <p>最后更新： 2017年09月15日 15:00</p>
        <p>原始链接： <a class="post-url" href="/2016/01/05/Android-IPC通讯Binder和Service的关系/" title="Android-IPC通讯Binder和Service的关系">http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/</a></p>
        <footer>
            <a href="http://mjjde.github.io">
                <img src="/images/avatar.jpg" alt="Joker Mei">
                Joker Mei
            </a>
        </footer>
    </div>
</div>

      
    </div>
    <footer class="article-footer">
        
        
<div class="post-share">
    <a href="javascript:;" id="share-sub" class="post-share-fab">
        <i class="fa fa-share-alt"></i>
    </a>
    <div class="post-share-list" id="share-list">
        <ul class="share-icons">
          <li>
            <a class="weibo share-sns" target="_blank" href="http://service.weibo.com/share/share.php?url=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/&title=《Android-IPC通讯Binder和Service的关系》 — 清风向阳&pic=http://mjjde.github.ioimages/avatar.jpg" data-title="微博">
              <i class="fa fa-weibo"></i>
            </a>
          </li>
          <li>
            <a class="weixin share-sns" id="wxFab" href="javascript:;" data-title="微信">
              <i class="fa fa-weixin"></i>
            </a>
          </li>
          <li>
            <a class="qq share-sns" target="_blank" href="http://connect.qq.com/widget/shareqq/index.html?url=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/&title=《Android-IPC通讯Binder和Service的关系》 — 清风向阳&source=
任何系统都有自己的跨进程通讯，Android是基于Linux，所以都会兼容Linux的通讯机制，包括有管道，信号，socket等等。基于Android自..." data-title="QQ">
              <i class="fa fa-qq"></i>
            </a>
          </li>
          <li>
            <a class="facebook share-sns" target="_blank" href="https://www.facebook.com/sharer/sharer.php?u=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/" data-title="Facebook">
              <i class="fa fa-facebook"></i>
            </a>
          </li>
          <li>
            <a class="twitter share-sns" target="_blank" href="https://twitter.com/intent/tweet?text=《Android-IPC通讯Binder和Service的关系》 — 清风向阳&url=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/&via=http://mjjde.github.io" data-title="Twitter">
              <i class="fa fa-twitter"></i>
            </a>
          </li>
          <li>
            <a class="google share-sns" target="_blank" href="https://plus.google.com/share?url=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/" data-title="Google+">
              <i class="fa fa-google-plus"></i>
            </a>
          </li>
        </ul>
     </div>
</div>
<div class="post-modal wx-share" id="wxShare">
    <a class="close" href="javascript:;" id="wxShare-close">×</a>
    <p>扫一扫，分享到微信</p>
    <img src="//api.qrserver.com/v1/create-qr-code/?data=http://mjjde.github.io/2016/01/05/Android-IPC通讯Binder和Service的关系/" alt="微信分享二维码">
</div>

<div class="mask"></div>

        
        <ul class="article-footer-menu">
            
            
  <li class="article-footer-tags">
    <i class="fa fa-tags"></i>
      
    <a href="/tags/Binder/" class="color2">Binder</a>
      
    <a href="/tags/Android-IPC/" class="color2">Android-IPC</a>
      
  </li>

        </ul>
        
    </footer>
  </div>
</article>


    <aside class="post-toc-pos post-toc-top" id="post-toc">
        <nav class="post-toc-wrap">
            <ol class="post-toc"><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#Binder机制"><span class="post-toc-text">Binder机制</span></a></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#基于Binder架构的代码设计"><span class="post-toc-text">基于Binder架构的代码设计</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-5"><a class="post-toc-link" href="#Service端设计"><span class="post-toc-text">Service端设计</span></a></li><li class="post-toc-item post-toc-level-5"><a class="post-toc-link" href="#Client端设计"><span class="post-toc-text">Client端设计</span></a></li><li class="post-toc-item post-toc-level-5"><a class="post-toc-link" href="#Service"><span class="post-toc-text">Service</span></a></li></ol></li><li class="post-toc-item post-toc-level-4"><a class="post-toc-link" href="#AIDL编写IPC通信"><span class="post-toc-text">AIDL编写IPC通信</span></a></li></ol>
        </nav>
    </aside>
    

<nav id="article-nav">
  
    <a href="/2016/01/15/android事件分发机制/" id="article-nav-newer" class="article-nav-link-wrap">

      <span class="article-nav-title">
        <i class="fa fa-hand-o-left" aria-hidden="true"></i>
        
          android事件分发机制
        
      </span>
    </a>
  
  
    <a href="/2015/12/28/Activity的进阶/" id="article-nav-older" class="article-nav-link-wrap">
      <span class="article-nav-title">Activity的进阶</span>
      <i class="fa fa-hand-o-right" aria-hidden="true"></i>
    </a>
  
</nav>



    
</section>
        
      </div>
      <footer id="footer">
  <div class="outer">
    <div id="footer-info" class="inner">
      
<p>
    <span id="busuanzi_container_site_uv" style='display:none'>
        总访客数：<span id="busuanzi_value_site_uv"></span>
    </span>
    <span id="busuanzi_container_site_pv" style='display:none'>
        总访问量：<span id="busuanzi_value_site_pv"></span>
    </span>
</p>


      <p>
        Powered by  <a href="http://hexo.io/" target="_blank">Hexo</a>
        Theme <a href="//github.com/wongminho/hexo-theme-miho" target="_blank">MiHo</a>
      &copy; 2018 Joker Mei<br>
      </p>
    </div>
  </div>
</footer>
    <script async src="//dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>
<script src="//cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
<script>
  var mihoConfig = {
      root: "http://mjjde.github.io",
      animate: false,
      isHome: false,
      share: true
  }
</script>
<div class="sidebar">
    <!-- <div id="sidebar-search" title="Search">
        <i class="fa fa-search"></i>
    </div> -->
    <div id="sidebar-category" title="Categories">
        <i class="fa fa-book"></i>
    </div>
    <div id="sidebar-tag" title="Tags">
        <i class="fa fa-tags"></i>
    </div>
    <div id="sidebar-top">
        <span class="sidebar-top-icon"><i class="fa fa-angle-up"></i></span>
    </div>
</div>
<div class="sidebar-menu-box" id="sidebar-menu-box">
    <div class="sidebar-menu-box-container">
        <div id="sidebar-menu-box-categories">
            <a class="category-link" href="/categories/Android技术/">Android技术</a><a class="category-link" href="/categories/其他技术/">其他技术</a><a class="category-link" href="/categories/网络技术/">网络技术</a><a class="category-link" href="/categories/设计模式/">设计模式</a>
        </div>
        <div id="sidebar-menu-box-tags">
            <a href="/tags/Activity/" style="font-size: 10px;">Activity</a> <a href="/tags/Android/" style="font-size: 16px;">Android</a> <a href="/tags/Android-IPC/" style="font-size: 10px;">Android-IPC</a> <a href="/tags/Binder/" style="font-size: 16px;">Binder</a> <a href="/tags/DiskLruCache/" style="font-size: 10px;">DiskLruCache</a> <a href="/tags/Fragment/" style="font-size: 10px;">Fragment</a> <a href="/tags/HTTP/" style="font-size: 20px;">HTTP</a> <a href="/tags/Java/" style="font-size: 10px;">Java</a> <a href="/tags/Notification/" style="font-size: 10px;">Notification</a> <a href="/tags/RemoteView/" style="font-size: 10px;">RemoteView</a> <a href="/tags/Rxjava/" style="font-size: 14px;">Rxjava</a> <a href="/tags/ServiceManager/" style="font-size: 14px;">ServiceManager</a> <a href="/tags/android/" style="font-size: 12px;">android</a> <a href="/tags/gradle/" style="font-size: 10px;">gradle</a> <a href="/tags/java/" style="font-size: 18px;">java</a> <a href="/tags/other/" style="font-size: 10px;">other</a> <a href="/tags/volley/" style="font-size: 12px;">volley</a> <a href="/tags/widget/" style="font-size: 10px;">widget</a> <a href="/tags/事件/" style="font-size: 10px;">事件</a> <a href="/tags/组件化/" style="font-size: 10px;">组件化</a> <a href="/tags/设计模式/" style="font-size: 18px;">设计模式</a>
        </div>
    </div>
    <a href="javascript:;" class="sidebar-menu-box-close">&times;</a>
</div>
<div class="mobile-header-menu-nav" id="mobile-header-menu-nav">
    <div id="mobile-header-menu-container">
        <span class="title">Menu</span>
        <ul class="mobile-header-menu-navbar">
            
            <li>
                <a  href="/">
                    <i class="fa fa-home"></i><span>Home</span>
                </a>
            </li>
            
            <li>
                <a  href="/archives">
                    <i class="fa fa-archive"></i><span>Archives</span>
                </a>
            </li>
            
            <li>
                <a  href="/about">
                    <i class="fa fa-user"></i><span>About</span>
                </a>
            </li>
            
        </ul>
    </div>
</div>
<div class="search-wrap">
    <span class="search-close">&times;</span>
        <a href="javascript:;" class="header-icon waves-effect waves-circle waves-light" id="back">
            <i class="icon icon-lg icon-chevron-left"></i>
        </a>
        <input class="search-field" placeholder="Search..." id="keywords">
        <a id="search-submit" href="javascript:;">
            <i class="fa fa-search"></i>
        </a>
    <div class="search-container" id="search-container">
        <ul class="search-result" id="search-result">
        </ul>
    </div>
</div>

<div id="search-tpl">
    <li class="search-result-item">
        <a href="{url}" class="search-item-li">
            <span class="search-item-li-title" title="{title}">{title}</span>
        </a>
    </li>
</div>
<script src="/js/search.js"></script>
<script src="/js/main.js"></script>








  </div>
</body>
</html>